package cn.cloud.project.consumer.config;

import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class ServiceChangeListener implements InitializingBean {

    private final NacosServiceManager nacosServiceManager;


    /**
     * 经过测试此处监听到的是当前服务的所有实例变化情况，不是某个实例变化情况。
     * 无法直接获取某个实例的变化情况，所以还需要自己维护实例列表
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        NamingService namingService = nacosServiceManager.getNamingService();
        try {
            namingService.subscribe("demo-provider", "DEFAULT_GROUP", new EventListener() {

                @Override
                public void onEvent(Event event) {
                    if (!(event instanceof NamingEvent)) {
                        return;
                    }

                    NamingEvent namingEvent = (NamingEvent) event;
                    List<Instance> instances = namingEvent.getInstances();
                    // 服务下线，且只有一台实例的情况下
                    if (instances.isEmpty()) {
                        log.info("服务下线 - 服务名: {}, 注意:该服务已全部下线", namingEvent.getServiceName());
                        return;
                    }
                    // 以下代码无效：namingEvent.getInstances() 无法获取下线了的服务
                    for (Instance instance : instances) {
                        if (instance.isHealthy()) {
                            // 实例状态为上线
                            log.info("服务上线 - 服务名: {}, 实例: {}:{}", instance.getServiceName(), instance.getIp(), instance.getPort());
                        } else {
                            // 实例状态为下线
                            log.info("服务下线 - 服务名: {}, 实例: {}:{}", instance.getServiceName(), instance.getIp(), instance.getPort());
                        }
                    }
                }
            });
        } catch (NacosException e) {
            log.error("监听nacos的服务实例变化情况失败", e);
        }
    }
}